package com.start.ws.connect;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.websocket.Session;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


@Schema(name = "用户连接")
public class StartUserConnect {

    @Schema(name = "用户连接")
    private final Map<String, List<Session>> clientTypeSessions;
    @Schema(name = "用户id")
    private final String userId;

    @Schema(name = "用户类型")
    private String startUserType;

    public StartUserConnect(String startUserType, String userId) {
        this(startUserType, userId, new ConcurrentHashMap<>());
    }

    public StartUserConnect(String startUserType, String userId, Map<String, List<Session>> clientTypeSessions) {
        assert userId != null;
        assert clientTypeSessions != null;
        this.userId = userId;
        this.clientTypeSessions = clientTypeSessions;
        this.startUserType = startUserType;

    }

    public Map<String, List<Session>> getClientTypeSessions() {
        return clientTypeSessions;
    }

    /**
     * 获取用户Session
     *
     * @param clientType
     * @return
     */
    public List<Session> getSession(String clientType) {
        if (!StringUtils.isEmpty(clientType)) {
            if (clientTypeSessions.containsKey(clientType)) {
                return clientTypeSessions.get(clientType);
            }
            return new ArrayList<>();
        }
        Collection<List<Session>> values = clientTypeSessions.values();
        List<Session> sessions = new ArrayList<>();
        values.forEach(sessions::addAll);
        return sessions;
    }

    public String getUserId() {
        return userId;
    }

    public void addSession(String clientType, Session session) {
        assert clientType != null;
        assert session != null;
        List<Session> sessions = null;
        if (!clientTypeSessions.containsKey(clientType)) {
            sessions = new ArrayList<>();
            clientTypeSessions.put(clientType, sessions);
        } else {
            sessions = clientTypeSessions.get(clientType);
        }
        sessions.add(session);
    }

    /**
     * 关闭全部
     */
    public void closeAll() {
        Collection<List<Session>> values = clientTypeSessions.values();
        clientTypeSessions.clear();
        values.forEach(e -> {
            e.forEach(s -> {
                try {
                    s.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                } finally {
                    e.clear();
                }
            });
        });
    }

    public List<String> allClientType() {
        Set<String> keys = clientTypeSessions.keySet();
        return new ArrayList<>(keys);
    }

    public boolean hasClientType(String clientType) {
        if (StringUtils.isEmpty(clientType)) return false;
        if (!clientTypeSessions.containsKey(clientType)) {
            return false;
        }
        List<Session> sessions = clientTypeSessions.get(clientType);
        return sessions != null && !sessions.isEmpty();
    }

    /**
     * 关闭指定客户端类型
     *
     * @param clientType
     */
    public void closeAll(String clientType) {
        assert clientType != null;
        if (!clientTypeSessions.containsKey(clientType)) return;
        List<Session> sessions = clientTypeSessions.remove(clientType);
        if (sessions.isEmpty()) {
            sessions = null;
            return;
        }
        sessions.forEach(e -> {
            try {
                e.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        });
        sessions.clear();
        sessions = null;
    }

    /**
     * 关闭指定客户端类型
     *
     * @param clientType
     */
    public void close(String clientType, String sessionId) {
        if (!clientTypeSessions.containsKey(clientType)) return;
        List<Session> sessions = clientTypeSessions.get(clientType);
        int len = sessions.size();
        int index = -1;
        for (int i = 0; i < len; i++) {
            if (sessionId.equals(sessions.get(i).getId())) {
                index = i;
                break;
            }
        }
        if (index < 0) return;
        sessions.remove(index);
    }

    public boolean sendMsg(String targetClientType, String msg) {
        List<Session> sessionList = getSession(targetClientType);
        if (sessionList == null || sessionList.isEmpty()) {
            return false;
        }
        for (Session session : sessionList) {
            if (!session.isOpen()) {
                continue;
            }
            try {
                session.getBasicRemote().sendText(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }
}
